<script lang="ts" setup>
import { reactive, ref, watch } from 'vue';

import {
  Button,
  Form,
  FormItem,
  Input,
  InputNumber,
  message,
  Modal,
  Select,
  SelectOption,
  Switch,
  Textarea,
} from 'ant-design-vue';

import {
  executeCapability,
  getCapabilityInstances,
} from '#/api/resource-center';

// Props
const props = defineProps<{
  visible: boolean;
}>();

// Emits
const emit = defineEmits<{
  success: [];
  'update:visible': [value: boolean];
}>();

// 响应式数据
const formRef = ref();
const submitting = ref(false);
const availableInstances = ref([]);
const selectedInstance = ref(null);

// 表单数据
const formData = reactive({
  capabilityInstanceId: '',
  parameters: {},
  context: {
    userId: '',
    sessionId: '',
    requestId: '',
  },
});

// 表单验证规则
const rules = {
  capabilityInstanceId: [
    { required: true, message: '请选择能力实例', trigger: 'change' },
  ],
  'context.userId': [
    { required: true, message: '请输入用户ID', trigger: 'blur' },
  ],
};

// 获取能力名称
const getCapabilityName = (capabilityId: string) => {
  const nameMap = {
    booking_capability: '预订能力',
    payment_capability: '支付能力',
    notification_capability: '通知能力',
    report_capability: '报表能力',
  };
  return nameMap[capabilityId] || capabilityId;
};

// 获取参数验证规则
const getParameterRules = (param: any) => {
  const rules = [];

  if (param.required) {
    rules.push({
      required: true,
      message: `请输入${param.description}`,
      trigger: 'blur',
    });
  }

  if (param.type === 'object') {
    rules.push({
      validator: (rule: any, value: any) => {
        if (value) {
          try {
            JSON.parse(value);
            return Promise.resolve();
          } catch {
            return Promise.reject('请输入有效的JSON格式');
          }
        }
        return Promise.resolve();
      },
      trigger: 'blur',
    });
  }

  return rules;
};

// 能力实例变化处理
const onInstanceChange = (value: string) => {
  selectedInstance.value = availableInstances.value.find(
    (instance) => instance.id === value,
  );

  // 重置参数
  formData.parameters = {};

  // 初始化默认参数值
  if (selectedInstance.value) {
    selectedInstance.value.parameters.forEach((param: any) => {
      if (param.defaultValue !== undefined) {
        formData.parameters[param.name] = param.defaultValue;
      }
    });
  }
};

// 加载可用实例
const loadAvailableInstances = async () => {
  try {
    const result = await getCapabilityInstances({ status: 'enabled' });
    if (result.code === 200) {
      availableInstances.value = result.data || [];
    }
  } catch (error) {
    console.error('加载能力实例失败:', error);
  }
};

// 监听visible变化
watch(
  () => props.visible,
  (visible) => {
    if (visible) {
      loadAvailableInstances();
      initializeForm();
    }
  },
);

// 初始化表单
const initializeForm = () => {
  Object.assign(formData, {
    capabilityInstanceId: '',
    parameters: {},
    context: {
      userId: '',
      sessionId: '',
      requestId: '',
    },
  });
  selectedInstance.value = null;
};

// 提交表单
const handleSubmit = async () => {
  try {
    await formRef.value?.validate();
    submitting.value = true;

    // 构建提交数据
    const submitData = {
      capabilityInstanceId: formData.capabilityInstanceId,
      resourceId: selectedInstance.value?.resourceId,
      parameters: formData.parameters,
      context: formData.context,
    };

    // 调用执行API
    const result = await executeCapability(submitData);

    if (result.code === 200) {
      message.success('执行成功');
      emit('success');
      handleCancel();
    } else {
      throw new Error('执行失败');
    }
  } catch (error) {
    console.error('执行失败:', error);
    message.error(`执行失败: ${(error as Error).message}`);
  } finally {
    submitting.value = false;
  }
};

// 取消
const handleCancel = () => {
  emit('update:visible', false);
};
</script>

<template>
  <Modal
    :visible="visible"
    title="执行能力"
    width="600px"
    :footer="null"
    :destroy-on-close="true"
    @update:visible="(val) => emit('update:visible', val)"
  >
    <Form
      ref="formRef"
      :model="formData"
      :rules="rules"
      :label-col="{ span: 6 }"
      :wrapper-col="{ span: 18 }"
      layout="horizontal"
    >
      <FormItem label="能力实例" name="capabilityInstanceId">
        <Select
          v-model="formData.capabilityInstanceId"
          placeholder="请选择能力实例"
          @change="onInstanceChange"
        >
          <SelectOption
            v-for="instance in availableInstances"
            :key="instance.id"
            :value="instance.id"
          >
            {{ instance.name }} ({{ getCapabilityName(instance.capabilityId) }})
          </SelectOption>
        </Select>
      </FormItem>

      <FormItem label="执行参数" name="parameters">
        <div class="parameters-editor">
          <div v-if="selectedInstance">
            <div
              v-for="param in selectedInstance.parameters"
              :key="param.name"
              class="parameter-item"
            >
              <FormItem
                :label="param.name"
                :name="['parameters', param.name]"
                :rules="getParameterRules(param)"
              >
                <Input
                  v-if="param.type === 'string'"
                  v-model="formData.parameters[param.name]"
                  :placeholder="`请输入${param.description}`"
                />
                <InputNumber
                  v-else-if="param.type === 'number'"
                  v-model="formData.parameters[param.name]"
                  :placeholder="`请输入${param.description}`"
                  style="width: 100%"
                />
                <Switch
                  v-else-if="param.type === 'boolean'"
                  v-model="formData.parameters[param.name]"
                />
                <Select
                  v-else-if="param.type === 'select'"
                  v-model="formData.parameters[param.name]"
                  :placeholder="`请选择${param.description}`"
                >
                  <SelectOption
                    v-for="option in param.options"
                    :key="option.value"
                    :value="option.value"
                  >
                    {{ option.label }}
                  </SelectOption>
                </Select>
                <Textarea
                  v-else-if="param.type === 'object'"
                  v-model:value="formData.parameters[param.name]"
                  :placeholder="`请输入JSON格式的${param.description}`"
                  :rows="3"
                />
                <Input
                  v-else
                  v-model:value="formData.parameters[param.name]"
                  :placeholder="`请输入${param.description}`"
                />
              </FormItem>
            </div>
          </div>
          <div v-else class="empty-state">
            <p>请先选择能力实例</p>
          </div>
        </div>
      </FormItem>

      <FormItem label="执行上下文" name="context">
        <div class="context-editor">
          <FormItem label="用户ID" name="context.userId">
            <Input
              v-model:value="formData.context.userId"
              placeholder="请输入用户ID"
            />
          </FormItem>
          <FormItem label="会话ID" name="context.sessionId">
            <Input
              v-model:value="formData.context.sessionId"
              placeholder="请输入会话ID"
            />
          </FormItem>
          <FormItem label="请求ID" name="context.requestId">
            <Input
              v-model:value="formData.context.requestId"
              placeholder="请输入请求ID"
            />
          </FormItem>
        </div>
      </FormItem>
    </Form>

    <div class="modal-footer">
      <Button @click="handleCancel">取消</Button>
      <Button type="primary" @click="handleSubmit" :loading="submitting">
        执行
      </Button>
    </div>
  </Modal>
</template>

<style lang="less" scoped>
.parameters-editor {
  .parameter-item {
    margin-bottom: 16px;
  }

  .empty-state {
    text-align: center;
    padding: 20px;
    color: #8c8c8c;
  }
}

.context-editor {
  .ant-form-item {
    margin-bottom: 16px;
  }
}

.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid #f0f0f0;
}
</style>
